import { InfoCircleOutlined } from '@ant-design/icons';
import { Form, Input, InputNumber, Modal, Radio, TreeSelect } from 'antd';
import { useImperativeHandle, useState } from 'react';

import menusApi from '@/api/menusApi';
import { message } from '@/components/AntdGlobal';
import { IMenu } from '@/types/api';
import type { IAction, IModalProp } from '@/types/modal';
import { normalizePath } from '@/utils';

const CreateMenu = (props: IModalProp<IMenu.EditParams | { parentId?: string; orderBy?: number }>) => {
    /* 数据管理 ---------------------------------------------------*/
    const [visible, setVisible] = useState(false);
    const [action, setAction] = useState<IAction>('create');
    const [form] = Form.useForm();
    const [menuList, setMenuList] = useState<IMenu.MenuItem[]>([]);
    const [confirmLoading, setConfirmLoading] = useState(false);

    /* 函数定义 ---------------------------------------------------*/
    /**暴露子组件open方法，供父组件中调用props.mRef?.openModal()方法
     *
     */
    useImperativeHandle(props.mRef, () => {
        return {
            openModal
        };
    });

    /**弹框显示
     * @param action 类型
     * @param data 数据
     */
    const openModal = async (action: IAction, data?: IMenu.EditParams | { parentId?: string; orderBy?: number }) => {
        setAction(action);
        setVisible(true);
        // 数据时效性，每次打开弹窗时重新获取数据
        await getMenusList();
        // 新增 or 编辑，表单赋值
        if (data && (action === 'create' || action === 'edit')) {
            form.setFieldsValue({ ...data });
        }
    };

    /**获取菜单列表
     */
    const getMenusList = async () => {
        const { data } = await menusApi.getMenusList();
        setMenuList(data);
    };

    /**提交操作
     */
    const handleSubmit = async () => {
        try {
            await form.validateFields();
            setConfirmLoading(true);

            const values = form.getFieldsValue();
            // 使用副本，不直接修改 form 内部数据
            const payload = { ...values } as IMenu.CreateParams & IMenu.EditParams;

            // 非按钮类型时，统一组装路由地址为绝对路径
            if (payload.menuType !== IMenu.EMenuType.BUTTON) {
                const rawPath = (payload.path || '').trim();
                if (!rawPath) {
                    message.error('路由地址不能为空');
                    setConfirmLoading(false);
                    return;
                }

                // 找到父节点的 path（若选了父级）
                const parent = menuList.find((menu) => menu.menuId === payload.parentId);
                const parentPath = parent?.path ?? '';

                let finalPath = '';
                if (!rawPath.startsWith('/')) {
                    // 相对路径 -> 拼接到父路径（若父路径存在），否则补全为 /xxx
                    if (parentPath) {
                        finalPath = `${parentPath.replace(/\/$/, '')}/${rawPath.replace(/^\//, '')}`;
                    } else {
                        finalPath = `/${rawPath.replace(/^\//, '')}`;
                    }
                } else {
                    // 绝对路径，保持但去除重复斜杠
                    finalPath = rawPath.replace(/\/{2,}/g, '/');
                }

                // 统一规范化（去末尾斜杠与查询参数）
                payload.path = normalizePath(finalPath);
            }

            // 简单重复校验：除当前编辑项外，不允许相同 path（可按需后端校验）
            if (payload.path) {
                const exists = menuList.find(
                    (menu) => menu.path && normalizePath(menu.path) === payload.path && menu.menuId !== payload.menuId
                );
                if (exists) {
                    message.error('路由地址已存在，请修改');
                    setConfirmLoading(false);
                    return;
                }
            }

            if (action === 'create') {
                await menusApi.createMenu(payload as IMenu.CreateParams);
                message.success('创建成功');
            } else {
                await menusApi.editMenu(payload as IMenu.EditParams);
                message.success('修改成功');
            }

            // 关闭弹窗，重置表单数据
            handleCancel();
            // 父组件更新列表
            props.update();
        } catch (error) {
            console.error(error);
        } finally {
            setConfirmLoading(false);
        }
    };

    /**取消操作
     */
    const handleCancel = () => {
        setVisible(false);
        form.resetFields();
    };
    return (
        <Modal
            title={action === 'create' ? '创建菜单' : '编辑菜单'}
            width={800}
            open={visible}
            okText="确定"
            cancelText="取消"
            onOk={handleSubmit}
            onCancel={handleCancel}
            confirmLoading={confirmLoading}
        >
            <Form
                form={form}
                labelAlign="right"
                labelCol={{ span: 4 }}
                initialValues={{ menuType: IMenu.EMenuType.MENU, menuState: IMenu.EMenuState.ENABLE }}
            >
                {/* 隐藏提交项,edit时提交 */}
                <Form.Item
                    hidden
                    name="menuId"
                >
                    <Input />
                </Form.Item>
                <Form.Item
                    label="父级菜单"
                    name="parentId"
                >
                    <TreeSelect
                        placeholder="请选择父级菜单"
                        allowClear
                        treeDefaultExpandAll
                        fieldNames={{ label: 'menuName', value: 'menuId' }}
                        treeData={menuList}
                    />
                </Form.Item>
                <Form.Item
                    label="菜单类型"
                    name="menuType"
                >
                    <Radio.Group>
                        <Radio value={IMenu.EMenuType.MENU}>菜单</Radio>
                        <Radio value={IMenu.EMenuType.BUTTON}>按钮</Radio>
                        <Radio value={IMenu.EMenuType.PAGE}>页面</Radio>
                    </Radio.Group>
                </Form.Item>
                <Form.Item
                    label="菜单名称"
                    name="menuName"
                    rules={[{ required: true, message: '请输入菜单名称' }]}
                >
                    <Input placeholder="请输入菜单名称" />
                </Form.Item>
                {/* 动态自定义渲染 */}
                <Form.Item
                    noStyle
                    shouldUpdate
                >
                    {() => {
                        return form.getFieldValue('menuType') === IMenu.EMenuType.BUTTON ? (
                            <Form.Item
                                label="权限标识"
                                name="menuCode"
                            >
                                <Input placeholder="请输入权限标识" />
                            </Form.Item>
                        ) : (
                            <>
                                <Form.Item
                                    label="菜单图标"
                                    name="icon"
                                >
                                    <Input placeholder="请输入菜单图标" />
                                </Form.Item>
                                <Form.Item
                                    label="路由地址"
                                    name="path"
                                    tooltip={{
                                        title: '末级菜单必填（可输入相对或绝对路径，提交时会被规范为绝对路径',
                                        icon: <InfoCircleOutlined />
                                    }}
                                    rules={[{ required: true, message: '请输入路由地址' }]}
                                >
                                    <Input placeholder="例如：/system/menuList 或 menuList" />
                                </Form.Item>
                            </>
                        );
                    }}
                </Form.Item>
                <Form.Item
                    label="排序"
                    name="orderBy"
                    tooltip={{
                        title: '排序值越大越靠后',
                        icon: <InfoCircleOutlined />
                    }}
                >
                    <InputNumber placeholder="请输入排序值" />
                </Form.Item>
                <Form.Item
                    label="菜单状态"
                    name="menuState"
                >
                    <Radio.Group>
                        <Radio value={IMenu.EMenuState.ENABLE}>启用</Radio>
                        <Radio value={IMenu.EMenuState.DISABLE}>停用</Radio>
                    </Radio.Group>
                </Form.Item>
            </Form>
        </Modal>
    );
};

export default CreateMenu;
